<template>
    <div>
        <!-- 行内搜素框以及功能按钮 -->
        <el-form :inline="true" class="demo-form-inline">
            <!-- 输入框 -->
            <el-form-item>
                <!-- 拥有一个清除的小按钮 使用的属性就是clearable属性 -->
                <el-input v-model="searchForm.username" placeholder="用户名" clearable size="large" />
            </el-form-item>
            <!-- 搜索按钮 -->
            <el-form-item>
                <el-button size="large" @click="getUserList">搜索</el-button>
            </el-form-item>
            <!-- 新增按钮 -->
            <el-form-item>
                <el-button type="primary" size="large" @click="addDialogVisible = true"
                    v-if="hasAuth('sys:user:save')">新增</el-button>
            </el-form-item>
            <!-- 删除按钮 -->
            <el-form-item>
                <!-- 气泡式弹出提示框 点击事件是confirm-->
                <el-popconfirm title="确定批量删除选中项？" confirm-button-text="确认" cancel-button-text="取消"
                    @confirm="deleteHandle(null)">
                    <template #reference>
                        <!-- 删除按钮是否能用 定义一个状态值给disabled，批量勾选中后实现可用效果 -->
                        <el-button type="danger" size="large" :disabled="delBtuStatu">批量删除</el-button>
                    </template>
                </el-popconfirm>
            </el-form-item>
        </el-form>

        <!-- 数据展示表格 -->
        <el-table ref="multipleTableRef" :data="tableData" style="width: 100%" @selection-change="handleSelectionChange"
            stripe border>
            <!-- 选择框 -->
            <el-table-column type="selection" width="55" />
            <!-- 头像 -->
            <el-table-column prop="avatar" label="头像" width="60">
                <template #default="scope">
                    <el-avatar size="small" :src="scope.row.avatar" />
                </template>
            </el-table-column>
            <el-table-column prop="username" label="用户名" width="80"></el-table-column>

            <el-table-column label="角色名称" show-overflow-tooltip width="180">
                <template #default="scope">
                    <el-tag size="small" type="info" v-for="item in scope.row.roles">{{ item.name }}</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="email" label="邮箱" width="150"></el-table-column>
            <el-table-column prop="phone" label="手机号" width="150"></el-table-column>

            <el-table-column property="statu" label="状态" width="80">
                <template #default="scope">
                    <el-tag :type="scope.row.statu === 1 ? 'success' : 'danger'">{{ scope.row.statu === 1 ? '正常' : '异常'
                        }}</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="created" label="创建时间"></el-table-column>
            <el-table-column prop="operate" label="操作" width="350">
                <!-- 行内插槽定义操作按钮 -->
                <template #default="scope">
                    <el-button type="text" @click="roleHandle(scope.row.id)" size="small">分配角色</el-button>
                    <!-- 分割线 -->
                    <el-divider direction="vertical"></el-divider>
                    <el-button type="text" @click="resetPwdHandle(scope.row.id, scope.row.username)"
                        size="small">重置密码</el-button>
                    <el-divider direction="vertical"></el-divider>
                    <el-button type="text" @click="editHandle(scope.row.id)" size="small">编辑</el-button>
                    <!-- 分割线 -->
                    <el-divider direction="vertical"></el-divider>
                    <!-- 气泡式弹出提示框 点击事件是confirm-->
                    <el-popconfirm title="确定删除该项？" confirm-button-text="确认" cancel-button-text="取消"
                        @confirm="deleteHandle(scope.row.id)">
                        <template #reference>
                            <el-button type="text" size="small">删除</el-button>
                        </template>
                    </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>

        <!-- 分页组件 -->
        <!-- 分页组件 同时汉化 -->
        <el-config-provider :locale="zhCn">
            <!-- pageSizes下拉后选择每一页数据有多少条 -->
            <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                layout="total, sizes, prev, pager, next, jumper" :page-sizes="[10, 20, 50, 100]" :current-page="current"
                :page-size="size" :total="total">
            </el-pagination>
        </el-config-provider>

        <!-- 新增弹出框 -->
        <el-dialog title="提示" v-model="addDialogVisible" width="600px" :before-close="handleClose">

            <el-form :model="addForm" :rules="addFormRules" ref="addFormRef">
                <el-form-item label="用户名" prop="username" label-width="100px">
                    <el-input v-model="addForm.username" autocomplete="off"></el-input>
                    <el-alert title="初始密码为888888" :closable="false" type="info" style="line-height: 12px;"></el-alert>
                </el-form-item>

                <el-form-item label="邮箱" prop="email" label-width="100px">
                    <el-input v-model="addForm.email" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="手机号" prop="phone" label-width="100px">
                    <el-input v-model="addForm.phone" autocomplete="off"></el-input>
                </el-form-item>

                <el-form-item label="状态" prop="statu" label-width="100px">
                    <el-radio-group v-model="addForm.statu">
                        <el-radio :label="0">禁用</el-radio>
                        <el-radio :label="1">正常</el-radio>
                    </el-radio-group>
                </el-form-item>

            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="addDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitForm(addFormRef)">确 定</el-button>
            </div>
        </el-dialog>


        <!-- 权限分配对话框 -->
        <!-- 分配权限对话框 -->
        <el-dialog title="分配角色" v-model="roleDialogFormVisible" width="600px" :before-close="handleRoleClose">
            <el-form :model="roleForm">
                <el-tree :data="roleTreeData" show-checkbox ref="treeRef" :check-strictly="true" node-key="id"
                    default-expand-all :props="defaultProps">
                </el-tree>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="roleDialogFormVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitRoleHandle(roleForm)">确 定</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup>
import {
    ElMessage,
    ElTable,
    FormInstance,
    FormRules,
    ElTree,
    ElMessageBox
} from "element-plus";
import { ref, reactive, getCurrentInstance, onMounted } from "vue";
// 导入中文包
import zhCn from "element-plus/es/locale/lang/zh-cn";
import { hasAuth } from "@/globalFunc";
// 获取axios实例
const { proxy } = getCurrentInstance() as any;

/********************************数据接口定义 ****************************/

// 用户信息
interface UserInfo {
    id: number,
    created?: string,
    updated?: string,
    statu?: number,
    username: string,
    password: string
    avatar: string,
    email?: string,
    city?: string | null,
    lastLogin?: string | null,
    roles?: Role[]
}
// 列表信息
interface ListInfo {
    records: UserInfo[],
    total: number,
    size: number,
    current: number,
    orders: any[], // 假设orders可以是任意类型的数组
    optimizeCountSql: boolean,
    hitCount: boolean,
    countId: null,
    maxLimit: null,
    searchCount: boolean,
    pages: number
}
// 搜索框信息
interface SearchForm {
    username?: string
}

// 新增对话框
interface AddForm {
    id?: number,
    username?: string,
    email?: string,
    phone?: string,
    statu?: number
}
/*********************************搜索框部分 *************************************/
// 定义表单实例和数据
const searchFormRef = ref<FormInstance>();
const searchForm = reactive<SearchForm>({});

/******************************表格数据定义相关 **********************************/

// 可选框的定义
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
const multipleSelection = ref<TableData[]>([]); // 选中的数据

// 定义数据
const tableData = ref<UserInfo[]>([]);

/**********************************分页组件 **********************************/
const total = ref(100);
const size = ref(10);
const current = ref(1);
const delBtuStatu = ref(false);
const handleSizeChange = (val: number) => {
    size.value = val;
    // 重新获取表格数据
};

const handleCurrentChange = (val: number) => {
    current.value = val;
    // 重新获取表格数据
};

// 实现勾选后调用函数
const handleSelectionChange = (selectRows: TableData[]) => {
    multipleSelection.value = selectRows;
    // 如果选中的行数大于0 删除按钮起作用
    delBtuStatu.value = selectRows.length === 0 ? true : false;
};

/******************************新增用户弹出对话框 *****************************/
const addDialogVisible = ref(false);
const addFormRef = ref<FormInstance>();
const addForm = ref<AddForm>({});

// 表单验证规则
const addFormRules = reactive<FormRules<AddForm>>({
    username: [
        { required: true, message: '请输入用户名称', trigger: 'blur' }
    ],
    email: [
        { required: true, message: '请输入邮箱', trigger: 'blur' }
    ],
    statu: [
        { required: true, message: '请选择状态', trigger: 'blur' }
    ]
});

// 表单重置
const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    formEl.resetFields();
};

// 弹窗关闭后操作
const handleClose = () => {
    // 取消弹窗显示
    addDialogVisible.value = false;
    // 清除表单内容
    resetForm(addFormRef.value);
}

/******************************分配角色表单和弹窗 ******************************/
interface RoleForm {
    id?: number;
    roles?: []
}
interface PermTreeData {
    id: number;
    name: string;
}
const roleDialogFormVisible = ref(false);
const defaultProps = {
    id: 'id',
    label: 'name',
}

const roleFormRef = ref<FormInstance>();
const roleForm = ref<RoleForm>({});

const roleTreeData = ref<PermTreeData[]>([]);
const treeRef = ref<InstanceType<typeof ElTree>>();

// 弹窗关闭后操作
const handleRoleClose = () => {
    // 取消弹窗显示
    addDialogVisible.value = false;
    // 清除表单内容
    resetForm(roleFormRef.value);
}
/*********************************后端接口调用 ********************************/
// 获取表格数据

const getUserList = () => {
    proxy.$axios.get('/sys/user/list',
        { // 携带参数的请求
            params: {
                username: searchForm.username,
                current: current.value,
                size: size.value
            }
        }).then((res: any) => {
            tableData.value = res.data.data.records;
            total.value = res.data.data.total;
            size.value = res.data.data.size;
            current.value = res.data.data.current;
        })
}

// 添加用户提交
// 提交按钮
const submitForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    formEl.validate((valid) => {
        if (valid) {
            // 表单验证通过，提交表单数据
            proxy.$axios
                .post("/sys/user/" + (addForm.value.id ? "update" : "save"), addForm.value)
                .then((res: any) => {
                    ElMessage({
                        type: "success",
                        message: res.data.msg, // 读取后端返回的信息
                        duration: 1000, // 控制弹出时长
                        onClose: () => {
                            // 关闭弹窗后执行的回调函数 更新表格数据
                            getUserList();
                        },
                    });
                    // 关闭编辑窗口
                    addDialogVisible.value = false;
                    // 清空表单数据
                    resetForm(addFormRef.value);
                });
        } else {
            // 表单验证失败
            return false;
        }
    });
};

// 点击编辑时数据的回显
const editHandle = (id: number) => {
    proxy.$axios.get('/sys/user/info/' + id).then((res: any) => {
        // 回显数据
        addForm.value = res.data.data;
        // 显示弹窗
        addDialogVisible.value = true;
    })
}

// 删除用户数据
const deleteHandle = (id: number | null) => {
    var ids: number[] = [];
    if (id) {
        ids.push(id);
    } else {
        multipleSelection.value.forEach(row => {
            ids.push(row.id);
        });
    }11
    // 请求后端接口
    proxy.$axios.post('/sys/user/delete', ids).then((res: any) => {
        ElMessage({
            type: 'success',
            message: res.data.msg,
            showClose: true,
            onClose: () => {
                // 刷新用户列表
                getUserList();
            }
        });
    })
}
// 获取角色树形结构的数据
const getTreeData = () => {
    proxy.$axios.get('/sys/role/list').then((res: any) => {
        // ts自动将目标结构拥有的数据按照数据名进行了填充
        roleTreeData.value = res.data.data.records;  
    })
}

// 分配角色功能
const roleHandle = (id: number) => {
    roleDialogFormVisible.value = true;
    // 请求后端接口，获取用户的角色信息
    proxy.$axios.get('/sys/user/info/' + id).then((res: any) => {
        roleForm.value = res.data.data;
        // 回显数据
        let roleIds: any = [];
        res.data.data.roles.forEach((row: any) => {
            roleIds.push(row.id);
        })
        // 选中到对应的树形结构上
        treeRef.value!.setCheckedKeys(roleIds, false);
    })
}

// 提交角色修改
const submitRoleHandle = (formName: RoleForm) => {
    var roleIds: any[] = treeRef.value!.getCheckedKeys(false);
    // 请求后端分配权限
    proxy.$axios.post('/sys/user/role/'+ roleForm.value.id, roleIds).then((res: any) => {
        ElMessage({
            type: 'success',
            message: res.data.data.msg,
            showClose: true,
            onClose: () => {
                roleDialogFormVisible.value = false;
                getUserList();
            }
        })
    })
}

// 重置用户密码
const resetPwdHandle = (id: number, username: string) => {
    ElMessageBox.confirm(`确认重置用户【${username}】的密码？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
    }).then(() => {
        // 请求后端接口，重置用户密码
        proxy.$axios.post('/sys/user/repass',id).then((res: any) => {
            ElMessage({
                type: 'success',
                message: res.data.msg,
                showClose: true
            })
        });
    });
}
/************************************钩子函数 ********************************/
onMounted(() => {
    getUserList();
    getTreeData();
})
</script>

<style>
.demo-form-inline .el-button {
    margin-left: -20px;
}

.el-tag {
    margin-left: 5px;
}

/* 分页组件css */
.el-pagination {
    float: right;
    margin-top: 22px;
}

.dialog-footer {
    text-align: center;
}
</style>